/*
 *  RationalElection.cpp
 *  VMF
 *
 *  Created by bdm on 6/24/10.
 *  Copyright 2010 Rochester Institute of Technology. All rights reserved.
 *
 */

#include <iostream>
#include "RationalElection.h"

// RationalElection - default constructor
RationalElection::RationalElection() : Election<RationalVote>() {}

// RationalElection
RationalElection::RationalElection( const set<string>& candidates ) : Election<RationalVote>( candidates ) {}

// RationalElection
RationalElection::RationalElection( const set<string>& candidates, const multiset<RationalVote>& votes ) : Election<RationalVote>( candidates, votes ) {}

//RationalElection
RationalElection::RationalElection( const RationalElection& election ) : Election<RationalVote>( election.get_candidates(), election.get_votes() ) {}

// validate_vote
int RationalElection::validate_vote( const RationalVote& vote ) const {
    // Check if the candidate set is a subset of the vote set.
    set<string> vote_set(vote.get_candidates());
    if( vote_set.size() == vote.get_preference_order().size() && vote_set.size() >= candidates_.size() ) {
        set<string>::const_iterator i = vote_set.begin();
        set<string>::const_iterator j = candidates_.begin();
        while( i != vote_set.end() && j != candidates_.end() ) {
            if( *j == *i ) {
                ++j;
            }
            ++i;
        }
        return j == candidates_.end();
    }
    else {
        return 0;
    }
}

void RationalElection::add_random_votes( unsigned int n, int print_votes ) {
    srand( time(NULL) );
    multiset<RationalVote> votes;
    for( unsigned int i = 0; i < n; ++i ) {
        vector<string> remaining( candidates_.begin(), candidates_.end() );
        vector<string> vote;
        while( remaining.size() ) {
            int index = rand() % remaining.size();
            vote.push_back( *(remaining.begin() + index) );
            remaining.erase( remaining.begin() + index );
        }
        add_vote( vote );
        votes.insert( vote );
    }
    if( print_votes ) {
        cout << "The following votes were added to the election:\n";
        map<RationalVote,int> vote_count;
        multiset<RationalVote>::iterator i = votes.begin();
        while( i != votes.end() ) {
            vote_count[*(i++)]++;
        }
        map<RationalVote,int>::iterator j = vote_count.begin();
        while( j != vote_count.end() ) {
            cout << j->first << ": " << j->second << "\n";
            ++j;
        }
    }
}
